home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Cheat II
/
cheatfile.c
< prev
next >
Wrap
Text File
|
1995-09-03
|
8KB
|
331 lines
// cheatfile.c
// saves the current data and scales 'n stuff
#include <Files.h>
#include <Pascal.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "main.h"
#include "cheatWindow.h"
#include "cheatprefs.h"
#include "cheat.h"
#include "cheatfile.h"
#include "resrefs.h"
#include "error.h"
#define cheatfilecreator 'chit'
#define cheatfiletype 'TEXT'
// externs
int wegotfile = 0;
// globs
int alreadysaved = false;
short VRefNum;
Str255 fname = "";
const char *sizestring[] = {
"Longint", "Integer", "Byte"
};
// when file name might have changed, we call this to change the append to button
static void updateappendoldbutt(void)
{
Str255 newt = "\pAppend To ";
int i;
wegotfile = true;
// append strings
for (i=0;i<fname[0];i++) {
newt[0]++;
newt[newt[0]] = fname[i+1];
}
SetCTitle((ControlHandle) sitem[riAppendToOld], newt); // change in shortcuts
fixshortbuttz();
}
// called when we're reading in from a file
static void addCheat(shortcut *ncut)
{
shortcut newcut;
Str255 s;
long l;
short id;
Cell cell, well = {0, 0};
Handle h;
newcut = *ncut;
// try to grow our records
SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
if (MemError()) {
stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
return;
}
HLock((Handle) cut);
(*cut)[gnumcuts] = newcut;
HUnlock((Handle) cut);
// add a cell in the list
cell.v = LAddRow(1, -1, slist);
cell.h = 0;
LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
gnumcuts++;
// add the resource to our file
h = NewHandle(sizeof(shortcut));
verify(h);
HLock(h);
**((shortcut **) h) = newcut;
HUnlock(h);
id = Unique1ID(kcheatsheettype);
AddResource(h, kcheatsheettype, id, newcut.title);
if (ResError())
stdmessage("\pI was unable to save this cheat.");
else {
WriteResource(h);
ReleaseResource(h);
}
}
#define kbufsize 700
// reads a file from disk, assumes name and vref already set
static void readFile(void)
{
short fref;
OSErr result;
long length;
Str255 str;
char buf[kbufsize], *c, *d, tmp[20];
int numvalid = 0;
shortcut ourcut;
short wedone = false;
result = FSOpen(fname, VRefNum, &fref);
if (result) { // no existing file forget it
SysBeep(1);
return;
}
// loop through trying to read the next cheat from the file
while (1) {
// read in some of the file, enough to fill buffer (maybe)
length = kbufsize - numvalid; // ask to fill buffer
if (length) {
result = FSRead(fref, &length, (Ptr) &buf[numvalid]); // get info
numvalid += length; // increase by number of bytes we read
// fine if less than requested
}
// advance past whitespace
c = buf;
if (isspace(*c)) while (isspace(*++c));
if (((long)c - (long)buf) >= numvalid)
break; // we're done done done
// read in title
if (*c != 'T') {
// stdmessage("\pError in parsing: Title not found.");
break; // probably done
}
c += 7; // length of "Title: "
d = c;
while (*++d != '\r') ; // find end of string
*d = 0; // never see it again, no matter
strcpy((char *)ourcut.title, c);
c = ++d;
if (isspace(*c)) while (isspace(*++c));
// read in comment
if (*c != 'C') {
stdmessage("\pError in parsing: Comment not found.");
break;
}
c += 9; // length of "Comment: "
if (*c == '\r')
ourcut.comment[0] = 0;
else {
wedone = false;
d = c;
while (!wedone) {
while (*++d != '\r') ; // find end of string
d++;
if ((long) d >= (long) buf + kbufsize) {
stdmessage("\pError in parsing: couldn't find \"Size\"");
result = FSClose(fref);
return;
}
if (!strncmp("Size:", d, 5))
wedone = true; // we done with comment
d--;
}
*d = 0; // never see it again, no matter
strcpy((char *)ourcut.comment, c);
c = ++d;
}
if (isspace(*c)) while (isspace(*++c));
// read in other stuff
d = c;
while (*++d != '\r') ; // find end of string
if (sscanf(c, "Size: %[^,], Offset: %ld, New value: %ld",
tmp, &ourcut.offset, &ourcut.newval) != 3) {
stdmessage("\pError in parsing: data ended too soon.");
break;
}
else {
ourcut.datasize = -1;
switch (tmp[0]) {
case 'B': case 'b': ourcut.datasize = ksizebyte; break;
case 'I': case 'i': ourcut.datasize = ksizeint; break;
case 'L': case 'l': ourcut.datasize = ksizelong; break;
default: stdmessage("\pError in parsing: illegal size type."); break;
}
if (ourcut.datasize < 0)
break;
// okay, we finally have a good new shortcut
CtoPstr((char *) ourcut.title);
CtoPstr((char *) ourcut.comment);
addCheat(&ourcut);
}
// scroll buffer down
c = d;
numvalid -= (long) c - (long) buf;
verify(numvalid >= 0);
memmove(buf, c, numvalid);
}
result = FSClose(fref);
fref = 0; // so we don't wipe out any disks (see THINK ref)
alreadysaved = true;
}
void OpenAppFile(void) // open the file passed by the finder
{
AppFile fd;
short message, count, i;
CountAppFiles(&message, &count);
if (count) {
GetAppFiles(1, &fd);
for (i=0;i<64;i++)
fname[i] = fd.fName[i];
VRefNum = fd.vRefNum;
readFile(); // read in info
ClrAppFiles(1);
updateappendoldbutt();
}
}
// called if user selects Open in the File menu
void doOpenFile(void)
{
Point pt;
SFReply reply;
SFTypeList tlist;
int i;
// use SF to let them select a file
SetPt(&pt, 100, 50);
tlist[0] = cheatfiletype;
SFGetFile(pt, "\pOpen file…", nil, 1, tlist, nil, &reply);
if (reply.good) {
// get name and vrefnum from reply
for (i=0;i<64;i++)
fname[i] = reply.fName[i];
VRefNum = reply.vRefNum;
readFile(); // read in info
updateappendoldbutt();
}
}
void doSaveFile(int howsave, shortcut *cut, int count)
{
long DirID, ThePrefs;
short fref;
OSErr result;
long length;
Point pt;
SFReply reply;
int i;
shortcut ourcut;
char buf[700];
if (howsave == knewfile) {
// use SF to let them select a file
SetPt(&pt, 100, 50);
SFPutFile(pt, "\pSave cheat as…", fname, nil, &reply);
if (reply.good) {
// get name and vrefnum from reply
for (i=0;i<64;i++)
fname[i] = reply.fName[i];
VRefNum = reply.vRefNum;
alreadysaved = true; // we are attached to this file now
updateappendoldbutt();
}
else
return;
// erase any existing file
result = FSDelete(fname, VRefNum);
result = Create(fname, VRefNum, cheatfilecreator, cheatfiletype); // make it
if (result) {
stdmessage("\pError: failed to create file");
return;
}
}
else if ((howsave == kappendnew) || !alreadysaved) {
SFTypeList tlist;
// use SF to let them select a file
SetPt(&pt, 100, 50);
tlist[0] = cheatfiletype;
SFGetFile(pt, "\pAppend to…", nil, 1, tlist, nil, &reply);
if (reply.good) {
// get name and vrefnum from reply
for (i=0;i<64;i++)
fname[i] = reply.fName[i];
VRefNum = reply.vRefNum;
alreadysaved = true;
updateappendoldbutt();
}
else
return;
}
else { // append to old one
}
result = FSOpen(fname, VRefNum, &fref); // still have to open it
if (result) { // no existing file forget it
stdmessage("\pError: failed to open file");
return;
}
result = SetFPos(fref, fsFromLEOF, 0); verify(!result); // so we append . . .
while (count--) {
ourcut = *cut;
PtoCstr(ourcut.title);
PtoCstr(ourcut.comment);
length = sprintf(buf, "Title: %s\15Comment: %s\15Size: %s, Offset: %ld, New value: %ld\15\15",
ourcut.title, ourcut.comment, sizestring[ourcut.datasize], ourcut.offset, ourcut.newval);
result = FSWrite(fref, &length, (Ptr) buf); // put info
cut++;
}
result = FSClose(fref);
result = FlushVol(0, 0);
if (result) Debugger();
fref = 0; // so we don't wipe out any disks (see THINK ref)
}